# Name: GUI.py #
# 
# Author: Waters #
# Creation Date: 2021.11.17 #
# Version: v0.0.2 #
# 

import os
import base64
import tkinter as TK
import tkinter.filedialog as TKFD
import tkinter.scrolledtext as ScrText
import re

from Icon import *


class MainWindow(object):
	"""docstring for MainWindow"""
	def __init__(self, g_obMainWindow):
		super(MainWindow, self).__init__()
		
		# Title
		g_szVersionNum = 'v0.0.0'
		g_obMainWindow.title('项目软件开发框架_%s' %g_szVersionNum)

		# Icon
		try:
			szIcon_Base64 = globals()[GetIconsVariableNames()[0]]
		except Exception as e:
			print('Error:%s\n' %e)
			print("Cannot find icon.\nPlease check './Icons/'.\n")
			return None
		with open ('IconTemp.ico', 'wb+') as fTempIcon:
			fTempIcon.write(base64.b64decode(szIcon_Base64))
		g_obMainWindow.iconbitmap('IconTemp.ico')
		os.remove('IconTemp.ico')

		# Position
		iScreenWidth = g_obMainWindow.winfo_screenwidth()
		iScreenHeight = g_obMainWindow.winfo_screenheight()
		iMainWindowWidth = iScreenWidth / 3
		iMainWindowHeight = iScreenHeight / 2.5
		iMainWindowPos_X = (iScreenWidth - iMainWindowWidth) / 2
		iMainWindowPos_Y = (iScreenHeight - iMainWindowHeight) / 3
		g_obMainWindow.geometry("%dx%d+%d+%d" %(iMainWindowWidth, iMainWindowHeight, iMainWindowPos_X, iMainWindowPos_Y))
		g_obMainWindow.resizable(1, 1)
		g_obMainWindow.minsize(int(iMainWindowWidth), int(iMainWindowHeight))

		# LabelFrames
		# Input & Output
		self.obFrame_IO = TK.LabelFrame(g_obMainWindow, text = "IO_Frame", labelanchor = "nw", bd = 2)
		self.obFrame_IO.pack(side = 'top', expand = 'yes', fill = 'x', padx = 10, pady = 10)
		# Buttons
		self.obFrame_Buttons = TK.LabelFrame(g_obMainWindow, text = "Buttons_Frame", labelanchor = "nw", bd = 2)
		self.obFrame_Buttons.pack(side = 'top', expand = 'yes', fill = 'x', padx = 10, pady = 10)
		# State & Error
		self.obFrame_States = TK.LabelFrame(g_obMainWindow, text = "States_Frame", labelanchor = "nw", bd = 2)
		self.obFrame_States.pack(side = 'top', expand = 'yes', fill = 'both', padx = 10, pady = 10)

		# IO Frame
		# Sub Frame
		subFrame_IOFrame_Top = TK.Frame(self.obFrame_IO)
		subFrame_IOFrame_Top.pack(side = 'top', expand = 'yes', fill = 'both', padx = 1, pady = 1)
		subFrame_IOFrame_Bottom = TK.Frame(self.obFrame_IO)
		subFrame_IOFrame_Bottom.pack(side = 'top', expand = 'yes', fill = 'both', padx = 1, pady = 1)
		# Label Input & Output
		self.obLabInputDir = TK.Label(subFrame_IOFrame_Top, text = '输入路径')
		self.obLabInputDir.pack(side = 'left', padx = 10, pady = 2)
		self.obLabOutputDir = TK.Label(subFrame_IOFrame_Bottom, text = '输出路径')
		self.obLabOutputDir.pack(side = 'left', padx = 10, pady = 2)
		# Entry Input & Output
		self.g_szInputDir = TK.StringVar()
		self.g_obEntInputDir = TK.Entry(subFrame_IOFrame_Top, textvariable = self.g_szInputDir)
		self.g_obEntInputDir.pack(side = 'left', expand = 'yes', fill = 'x', padx = 10, pady = 2)
		self.g_szOutputDir = TK.StringVar()
		self.g_obEntOutputDir = TK.Entry(subFrame_IOFrame_Bottom, textvariable = self.g_szOutputDir)
		self.g_obEntOutputDir.pack(side = 'left', expand = 'yes', fill = 'x', padx = 10, pady = 2)
		# Button Input & Output
		self.obButInputDir = TK.Button(subFrame_IOFrame_Top, text = '浏览', command = lambda: self.SelectIODir(self.g_szInputDir))
		self.obButInputDir.pack(side = 'left', padx = 10, pady = 2)
		self.obButOutputDir = TK.Button(subFrame_IOFrame_Bottom, text = '浏览', command = lambda: self.SelectIODir(self.g_szOutputDir))
		self.obButOutputDir.pack(side = 'left', padx = 10, pady = 2)

		# Buttons Frame
		self.obButStartProc = TK.Button(self.obFrame_Buttons, text = 'Start', command = lambda: self.StartProcess())
		self.obButStartProc.pack(side = 'top', expand = 'yes', fill = 'none', padx = 10, pady = 10)

		# State & Error Frame
		# Sub Frame
		subFrame_StateFrame = TK.Frame(self.obFrame_States)
		subFrame_StateFrame.pack(side = 'left', expand = 'yes', fill = 'both', padx = 1, pady = 1)
		subFrame_ErrorFrame = TK.Frame(self.obFrame_States)
		subFrame_ErrorFrame.pack(side = 'left', expand = 'yes', fill = 'both', padx = 1, pady = 1)
		
		# State Frame
		subFrame_StateFrame_Top = TK.Frame(subFrame_StateFrame)
		subFrame_StateFrame_Top.pack(side = 'top', expand = 'yes', fill = 'x', padx = 1, pady = 1)
		subFrame_StateFrame_Bottom = TK.Frame(subFrame_StateFrame)
		subFrame_StateFrame_Bottom.pack(side = 'top', expand = 'yes', fill = 'both', padx = 1, pady = 1)
		# Label RunState
		self.obLabRunState = TK.Label(subFrame_StateFrame_Top, text = '运行状态')
		self.obLabRunState.pack(side = 'left', expand = 'yes', fill = 'none', padx = 1, pady = 1)
		# Label Statistic
		self.g_szStatistic = TK.StringVar()
		self.g_szStatistic.set('0/0')
		self.obLabStatistic = TK.Label(subFrame_StateFrame_Top, textvariable = self.g_szStatistic)
		self.obLabStatistic.pack(side = 'left', expand = 'yes', fill = 'x', padx = 1, pady = 1)
		# Button Clear Scrolled Text
		self.obButClearState = TK.Button(subFrame_StateFrame_Top, text = '清空', command = lambda: self.ClearScrollText(self.g_obSTRunState))
		self.obButClearState.pack(side = 'left', expand = 'yes', fill = 'none', padx = 1, pady = 1)
		# Scroll Text RunState
		self.g_obSTRunState = ScrText.ScrolledText(subFrame_StateFrame_Bottom, width = int(iMainWindowWidth / 20), height = int(iMainWindowHeight / 5))
		self.g_obSTRunState.pack(side = 'left', expand = 'yes', fill = 'both', padx = 1, pady = 1)

		# Error Frame
		subFrame_ErrorFrame_Top = TK.Frame(subFrame_ErrorFrame)
		subFrame_ErrorFrame_Top.pack(side = 'top', expand = 'yes', fill = 'x', padx = 1, pady = 1)
		subFrame_ErrorFrame_Bottom = TK.Frame(subFrame_ErrorFrame)
		subFrame_ErrorFrame_Bottom.pack(side = 'top', expand = 'yes', fill = 'both', padx = 1, pady = 1)
		# Label Error
		self.obLabError = TK.Label(subFrame_ErrorFrame_Top, text = '错误信息')
		self.obLabError.pack(side = 'left', expand = 'yes', fill = 'none', padx = 1, pady = 1)
		# Button Clear Scrolled Text
		self.obButClearError = TK.Button(subFrame_ErrorFrame_Top, text = '清空', command = lambda: self.ClearScrollText(self.g_obSTError))
		self.obButClearError.pack(side = 'left', expand = 'yes', fill = 'none', padx = 1, pady = 1)
		# Scroll Text Error
		self.g_obSTError = ScrText.ScrolledText(subFrame_ErrorFrame_Bottom, width = int(iMainWindowWidth / 20), height = int(iMainWindowHeight / 5))
		self.g_obSTError.pack(side = 'left', expand = 'yes', fill = 'both', padx = 1, pady = 1)

	# Select IO directory.
	def SelectIODir(self, szTargetDir):
		temp_szIODirectory = TKFD.askdirectory()
		if ('' == temp_szIODirectory):
			szTargetDir.set('C:/')
		else:
			szTargetDir.set(temp_szIODirectory)
		return 0

	def StartProcess(self):
		self.g_obSTRunState.insert('end', 'Template Start.\n')
		self.g_obSTRunState.see('end')
		self.g_obSTError.insert('end', 'Template Error.\n')
		self.g_obSTError.see('end')
		return 0

	def ClearScrollText(self, obSTTargetScrText):
		try:
			obSTTargetScrText.delete(0.0,'end')
			self.g_szStatistic.set('0/0')
		except Exception as e:
			self.g_obSTError.insert('end', e)
			self.g_obSTError.see('end')
		return 0

def GetIconsVariableNames():
	lszIconVariableNames = []
	temp_GlobalVariablesKeys = list(globals().keys())
	for eachKey in temp_GlobalVariablesKeys:
		if(re.match('szIcon_', eachKey)):
			lszIconVariableNames.append(eachKey)
		else:
			pass
	return lszIconVariableNames


if __name__ == '__main__':
	g_obMainWindow = TK.Tk()
	obMainWindow = MainWindow(g_obMainWindow)
	g_obMainWindow.mainloop()